home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / DASHANIM.ZIP / PLAYDSH.ZIP / DASHANIM.CPP next >
Encoding:
C/C++ Source or Header  |  1995-03-26  |  6.3 KB  |  220 lines

  1. //DASHANIM.CPP--  Methods file for routines that play .DSH animation files
  2. //                created by PCX2DSH.
  3. //                (C) 1995 Eric M. Dashofy / Archon Software
  4. //          All Rights Reserved
  5.  
  6. //Note:  Must be cross-compiled with XMM.CPP
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <dos.h>
  11. #include <conio.h>
  12. #include "xmm.h"
  13. #include "dashanim.h"
  14.  
  15. word dsh_flood_buffer(buf_struct& buffer){
  16.   long position = ftell(buffer.file);
  17.   long filelen  = buffer.hdr.FileLength;
  18.   word bytes_to_read = buf_size;
  19.   if ((filelen - position) < buffer.buf_size){
  20.     bytes_to_read = (filelen - position);
  21.   }
  22.   fread(buffer.buf_ptr, sizeof(byte), bytes_to_read, buffer.file);
  23.   buffer.bytes_read = bytes_to_read;
  24.   buffer.offset = 0;
  25.   return bytes_to_read;
  26. }
  27.  
  28. void dsh_get_header(FILE* stream, DSH_Header& hdr){
  29.   fread(&hdr, sizeof(hdr), 1, stream);
  30. }
  31.  
  32. word dsh_xms_flood_buffer(DashXMM& AnimXMS, buf_struct& buffer){
  33.   word bytes_to_read = buf_size;
  34.   if ((buffer.hdr.FileLength - AnimXMS.index) < buffer.buf_size){
  35.     bytes_to_read = (buffer.hdr.FileLength - AnimXMS.index);
  36.   }
  37.   AnimXMS.move(bytes_to_read, (void far*) buffer.buf_ptr, AnimXMS.index);
  38.   buffer.bytes_read = bytes_to_read;
  39.   buffer.offset = 0;
  40.   AnimXMS.index += bytes_to_read;
  41.   return bytes_to_read;
  42. }
  43.  
  44. void dsh_get_bytes(byte far* to, word num_bytes, buf_struct& buffer,
  45.            DashXMM& AnimXMS){
  46.   word btm = 0;
  47.   word to_offset = 0;
  48.   /*
  49.   while (bytes_copied < num_bytes){
  50.     if ((buffer.bytes_read == buffer.offset))
  51.       dsh_xms_flood_buffer(AnimXMS, buffer);
  52.     to[bytes_copied] = buffer.buf_ptr[buffer.offset];
  53.     bytes_copied++;
  54.     buffer.offset++;
  55.   }
  56.   */
  57.   if (buffer.offset == buffer.bytes_read)
  58.       dsh_xms_flood_buffer(AnimXMS, buffer);  //flood the buffer
  59.  
  60.  
  61.   btm = num_bytes;  //move all bytes;
  62.   while((buffer.offset + btm) > buffer.bytes_read){
  63.     if ((buffer.offset + btm) > buffer.bytes_read){
  64.       //if we will go past the end of the buffer, copy to end first
  65.       btm = buffer.bytes_read - buffer.offset;  //bytes to read = rest of buffer
  66.       memcpy((void far*)&to[to_offset], (void far*)&buffer.buf_ptr[buffer.offset],
  67.          btm);
  68.       to_offset += btm;  //inc. to_offset for rest of move
  69.       btm = num_bytes - btm;  //set rest of bytes to move
  70.       dsh_xms_flood_buffer(AnimXMS, buffer);  //flood the buffer
  71.     }
  72.   }
  73.  
  74.   memcpy((void far*)&to[to_offset], (void far*)&buffer.buf_ptr[buffer.offset],
  75.      btm);  //move bytes (rest of bytes if already did some)
  76.   buffer.offset += btm;
  77. }
  78.  
  79.  
  80. void set_palette(byte* pal){
  81.   /*
  82.   _AH = 0x10;
  83.   _AL = 0x12;
  84.   _BX = 0;
  85.   _CX = 0x100;
  86.   _ES = FP_SEG(pal);
  87.   _DX = FP_OFF(pal);
  88.   geninterrupt(0x10);
  89.   */
  90.   int port1 = 0x3c8;
  91.   int port2 = 0x3c9;
  92.   char nullchar='\0';
  93.   outportb(port1,nullchar); //initialize EGA/VGA to read 768 palette regs
  94.  
  95.   for (short i=0; i<768; i++){
  96.     outportb(port2,pal[i]);
  97.   }
  98. }
  99.  
  100. void setmode(byte mode){
  101.    //_AL = mode;
  102.    //_AH = 0;
  103.    //geninterrupt(0x10);
  104.    asm{
  105.      mov al, mode
  106.      mov ah, 0
  107.      int 10h
  108.    }
  109. }
  110.  
  111. int playdsh(char* afn, unsigned int delayms){
  112.   DashXMM AnimXMS (FALSE);  //open xms for animation, no swapfile, not verbose
  113.  
  114.   //this program's purpose is to play a .DSH animation file quickly.
  115.  
  116.   //we're going to forego the details and do this one:
  117.  
  118.   int oldmode=*(int *)MK_FP(0x40,0x49); // Set VGA mode...
  119.   setmode(0x13);                       // to 320x200x256
  120.  
  121.   FILE* DashFile;
  122.   if ((DashFile = fopen(afn, "rb")) == NULL){
  123.     setmode (oldmode);
  124.     fprintf(stderr, "Cannot open %s.\n", afn);
  125.  
  126.     return 1;
  127.   }
  128.   DSH_Header hdr;
  129.   dsh_get_header (DashFile, hdr);
  130.  
  131.   //now, with the header, we can allocate the proper amount of XMS with the
  132.   //filesize contained therein
  133.  
  134.   AnimXMS.allocate(hdr.FileLength + 20);
  135.   AnimXMS.index = sizeof(hdr);
  136.  
  137.   //set the buffer
  138.   buf_struct buffer;
  139.   buffer.file = DashFile;
  140.   buffer.buf_size = buf_size;
  141.   buffer.hdr = hdr;
  142.   buffer.bytes_read = 0;
  143.   buffer.offset = 0;
  144.   buffer.buf_ptr = new byte[buf_size];  //allocate
  145.   if (buffer.buf_ptr == NULL){
  146.     setmode(oldmode);
  147.     printf("\nSorry, not enough memory to allocate buffer!\n");
  148.     return 1;
  149.   }
  150.  
  151.   //this buffer will now be used, briefly, to buffer the input file into XMS
  152.   fseek(DashFile, 0, 0);  //reset the file
  153.   dword   bytes_to_read = hdr.FileLength;
  154.   dword   bytes_to_move = 0;
  155.   boolean move_complete = FALSE;
  156.   dword   xms_offset    = 0;
  157.   do{
  158.     bytes_to_move = buf_size;
  159.     if (bytes_to_move > bytes_to_read){
  160.       bytes_to_move = bytes_to_read;
  161.       move_complete = TRUE;
  162.     }
  163.     fread(buffer.buf_ptr, 1, bytes_to_move, DashFile);
  164.     AnimXMS.move(bytes_to_move, xms_offset, (void far*)buffer.buf_ptr);
  165.     bytes_to_read -= bytes_to_move;
  166.     xms_offset += bytes_to_move;
  167.   }while(!move_complete);
  168.   //there.  The input file is now completely in XMS.
  169.  
  170.   //go on
  171.   byte far* ScreenPtr = (byte far*)MK_FP(0xA000, 0);
  172.   word ScreenOffset = 0;
  173.   byte  Palette[768];
  174.  
  175.   byte  br;
  176.   byte  curmode;
  177.   word  wr;
  178.   byte* p_wr = &((byte)wr);
  179.   dword dwr;
  180.  
  181.   dsh_get_bytes(&br, 1, buffer, AnimXMS);        //should be 0xFF - NewFrame
  182.  
  183.   dsh_get_bytes(Palette, 768, buffer, AnimXMS);
  184.   set_palette(Palette);
  185.   dsh_get_bytes(ScreenPtr, 64000U, buffer, AnimXMS);
  186.  
  187.   int i = 0;
  188.   for (i = 1; i < hdr.NumFrames; i++){
  189.     ScreenOffset = 0;
  190.     dsh_get_bytes(&br, 1, buffer, AnimXMS); //should be 0xFF - NewFrame
  191.     if (delayms > 0) delay(delayms);
  192.     //reintroduce next line for debugging
  193.     //if (br != NewFrame) break;
  194.     dsh_get_bytes(Palette, 768, buffer, AnimXMS);    //get frame palette
  195.     set_palette(Palette);                   //set frame palette
  196.     do{
  197.       dsh_get_bytes(&curmode, 1, buffer, AnimXMS);     //get mode
  198.       if (curmode == SkipMode){
  199.     dsh_get_bytes(p_wr, 2, buffer, AnimXMS);  //get # to skip
  200.     ScreenOffset += (wr);                        //skip bytes
  201.       }
  202.       if (curmode == WriteMode){
  203.     dsh_get_bytes(p_wr, 2, buffer, AnimXMS);  //get # to write
  204.     dsh_get_bytes(ScreenPtr + ScreenOffset, wr, buffer, AnimXMS);
  205.                             //Write 'em
  206.     ScreenOffset += (wr);
  207.       }
  208.       //reintroduce next line for debugging
  209.       //if ((curmode != SkipMode) && (curmode != WriteMode)) break;
  210.     }while (ScreenOffset != 63999U);
  211.   }
  212.  
  213.   fclose(DashFile);
  214.   AnimXMS.free();
  215.   delete buffer.buf_ptr;
  216.   setmode(oldmode);
  217.   return 0;
  218.  
  219. }
  220.